package com.example.service.impl;

import com.example.config.ClientConfig;
import com.example.service.IpfsService;
import com.example.service.TraceFromSourceService;
import com.example.utils.ContractAddressManager;
import com.example.utils.LSHUtil;
import com.example.utils.PropertyUtil;
import lombok.extern.slf4j.Slf4j;
import org.fisco.bcos.sdk.client.Client;
import org.fisco.bcos.sdk.transaction.manager.AssembleTransactionProcessor;
import org.fisco.bcos.sdk.transaction.manager.TransactionProcessorFactory;
import org.fisco.bcos.sdk.transaction.model.dto.TransactionResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@Service
@Slf4j
public class TraceFromSourceServiceImpl implements TraceFromSourceService {

    public static final String TraceToTheSourceABI = com.example.utils.IOUtil.readResourceAsString("abi/TraceToTheSource.abi");
    private final String TraceToTheSourceAddress = ContractAddressManager.getAddressFromContractNote("TraceToTheSource");

    public static final String UserRegistryABI = com.example.utils.IOUtil.readResourceAsString("abi/UserRegistry.abi");
    private String UserRegistryAddress = ContractAddressManager.getAddressFromContractNote("UserRegistry");


    @Autowired
    private Client client;

    AssembleTransactionProcessor txProcessor;
    String clientPri;
    @Autowired
    private IpfsService ipfsService;
    @Override
    public  ArrayList<String> traceFromSource(MultipartFile file) throws Exception {
        //登录信息
        String userName = PropertyUtil.getUserName();
        AccountManager.loadP12Account(client, ClientConfig.account_keyfile_path + userName, ClientConfig.account_password);
        this.txProcessor = TransactionProcessorFactory.createAssembleTransactionProcessor(this.client, this.client.getCryptoSuite().getCryptoKeyPair());
        this.clientPri = client.getCryptoSuite().getCryptoKeyPair().getHexPrivateKey();
        //获取源文件名
        String originalFilename = file.getOriginalFilename();
        //形成临时文件
        File tempFile = File.createTempFile("upload_", "_" + originalFilename);
        file.transferTo(tempFile);
        //获取文件的哈希数组
        long[] hashKey = LSHUtil.getHashKey(tempFile.getAbsolutePath());
        //对哈希数组进行处理，方便上传到区块链中
        ArrayList<BigInteger> hashKeyList = new ArrayList<>();
        for(int i = 0; i < hashKey.length; i++){
            hashKeyList.add(BigInteger.valueOf(hashKey[i]));
        }

        BigInteger[] hashKeyArr = hashKeyList.toArray(new BigInteger[0]);
        // log.info("哈希哈希哈希:{}", (Object) hashKeyArr);
        //智能合约函数对应的参数
        List<Object> args = new ArrayList<>();
        Collections.addAll(args, hashKeyArr, ClientConfig.threshold);

        //log.info("参数：{}", args);
        //System.out.println("溯源的hashkey：" + Arrays.toString(hashKeyArr));
        //形成交易区块
        TransactionResponse addRecord = this.txProcessor.sendTransactionAndGetResponse(TraceToTheSourceAddress, TraceToTheSourceABI, "findPathbyhash", args);
        //获取区块链函数返回值
        ArrayList<String> str  = (ArrayList<String>) addRecord.getReturnObject().get(0);
        //log.info("返回值 : {}", str);
        tempFile.delete();
        return str;

    }

}
